package com.bs.service;

import com.bs.domain.ServiceInfo;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.aggregations.metrics.max.MaxBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @Author: rui xu
 * @Date: 2019/3/20 16:06
 */

@Service
public class TransferCountService {


    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;

    private String partition;
    private String logmsg;
    private String startTime;
    private String endTime;
    private String code;
    private String active;


    /**
     * 服务调用top10  and 电文service调用Top10
     *
     * @return
     */
    private SearchResponse getCallServiceResponse() {
        String index = "logstash-*-" + active + "-svcsql-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();


        builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", logmsg));
        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        } else {
            if (("4. service end.").equals(logmsg)) {
                // !svc:ep* && !uid:"xcom"
                builder.mustNot(QueryBuilders.wildcardQuery("svc", "ep?*"))
                    .mustNot(QueryBuilders.termQuery("uid", "xcom"));
            }
        }
        if (!code.equals("")) {
            index = "logstash-" + code + "-svcsql-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("category", "SVCSQL"))
                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder svcAgg = AggregationBuilders.terms("services").field("svc")
            .size(10);


        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(svcAgg)
            .execute().actionGet();
    }

    public List<ServiceInfo> callServiceTop10(String partition, String logmsg, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.logmsg = logmsg;
        this.code = code;
        this.active = active;
        SearchResponse response = getCallServiceResponse();
        ArrayList<ServiceInfo> arrayList = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
        StringTerms servicesStringTerms = (StringTerms) response.getAggregations().getAsMap().get("services");
            Iterator<Terms.Bucket> iterator = servicesStringTerms.getBuckets().iterator();
            while (iterator.hasNext()) {
                Terms.Bucket next = iterator.next();
                String svc = (String) next.getKey();
                long docCount = next.getDocCount();
                arrayList.add(new ServiceInfo(svc, docCount, ""));
            }
        }

        return arrayList;
    }

    /***
     *   用户调用
     * @return
     */

    private SearchResponse getUidServiceResponse() {
        String index = "logstash-*-" + active + "-svcsql-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", "4. service end."));
        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        } else {
            // !svc:ep* && !uid:"xcom"
            builder.mustNot(QueryBuilders.wildcardQuery("svc", "ep?*"))
                .mustNot(QueryBuilders.termQuery("uid", "xcom"));
        }


        if (!code.equals("")) {
            index = "logstash-" + code + "-svcsql-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("category", "SVCSQL"))
                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder uidAgg = AggregationBuilders.terms("uid").field("uid")
            .size(10);
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(uidAgg)
            .execute().actionGet();
    }

    public List<ServiceInfo> uidServiceTop10(String partition, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.code = code;
        this.active = active;
        SearchResponse response = getUidServiceResponse();
        ArrayList<ServiceInfo> arrayList = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms servicesStringTerms = (StringTerms) response.getAggregations().getAsMap().get("uid");

            Iterator<Terms.Bucket> iterator = servicesStringTerms.getBuckets().iterator();
            while (iterator.hasNext()) {
                Terms.Bucket next = iterator.next();
                String uid = (String) next.getKey();
                long docCount = next.getDocCount();
                arrayList.add(new ServiceInfo(uid, docCount, ""));
            }
        }
        return arrayList;
    }


    /**
     * 批作业执行Top10
     *
     * @return
     */
    private SearchResponse getBatchServiceResponse() {
        String index = "logstash-*-" + active + "-svcsql-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", "2. batch"));
        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        }

        if (!code.equals("")) {
            index = "logstash-" + code + "-svcsql-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("category", "SVCSQL"))
                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder svcAgg = AggregationBuilders.terms("services").field("svc")
            .size(10);
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(svcAgg)
            .execute().actionGet();
    }

    public List<ServiceInfo> batchServiceTop10(String partition, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.code = code;
        this.active = active;
        SearchResponse response = getBatchServiceResponse();
        ArrayList<ServiceInfo> arrayList = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms servicesStringTerms = (StringTerms) response.getAggregations().getAsMap().get("services");
            Iterator<Terms.Bucket> iterator = servicesStringTerms.getBuckets().iterator();
            while (iterator.hasNext()) {
                Terms.Bucket next = iterator.next();
                String svc = (String) next.getKey();
                long docCount = next.getDocCount();
                arrayList.add(new ServiceInfo(svc, docCount, ""));
            }
        }
        return arrayList;
    }


    /**
     * 异步路由电文号Top10
     *
     * @return
     */
    private SearchResponse getAsyncRouteServiceResponse() {
        String index = "logstash-*-" + active + "-comm-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();

        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        } else {
            builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", "Routing-async"))
                .mustNot(QueryBuilders.wildcardQuery("tc_no", "NG*"));
        }

        if (!code.equals("")) {
            index = "logstash-" + code + "-comm-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("category", "COMM"))
                .must(QueryBuilders.existsQuery("tc_no"))
                .mustNot(QueryBuilders.termQuery("tc_no"," "))
                .must(QueryBuilders.boolQuery()
                    .should(QueryBuilders.termQuery("progress_seq", "600"))
                    .should(QueryBuilders.termQuery("progress_seq", "100")))

                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder tcNoAgg = AggregationBuilders.terms("tc_no").field("tc_no")
            .size(10);
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(tcNoAgg)
            .execute().actionGet();
    }

    public List<ServiceInfo> asyncRouteServiceTop10(String partition, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;

        this.code = code;
        this.active = active;
        SearchResponse response = getAsyncRouteServiceResponse();
        ArrayList<ServiceInfo> arrayList = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms servicesStringTerms = (StringTerms) response.getAggregations().getAsMap().get("tc_no");
            Iterator<Terms.Bucket> iterator = servicesStringTerms.getBuckets().iterator();
            while (iterator.hasNext()) {
                Terms.Bucket next = iterator.next();
                String tcNo = (String) next.getKey();
                long count = next.getDocCount();
                arrayList.add(new ServiceInfo(tcNo, count, ""));
            }
        }
        return arrayList;
    }


    /**
     * 画面调用Top10
     *
     * @return
     */
    private SearchResponse getCallFrameServiceResponse() {
        String index = "logstash-*-" + active + "-epes-*";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        if (partition.indexOf("CMS") == -1) {
            builder.filter(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("partition", partition)));
        }

        if (!code.equals("")) {
            index = "logstash-" + code + "-epes-*";
        }
        builder.filter(
            QueryBuilders.boolQuery().must(QueryBuilders.termQuery("key1.raw", "ACCESSFORM"))
                .mustNot(QueryBuilders.wildcardQuery("key5.raw", "EP*"))
                .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00")));
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
        TermsBuilder frameNameAgg = AggregationBuilders.terms("frameName").field("key5.raw")
            .size(10);
        return searchRequestBuilder
            .setSize(0)
            .setQuery(builder)
            .addAggregation(frameNameAgg)
            .execute().actionGet();
    }

    public List<ServiceInfo> callFrameServiceTop10(String partition, String startTime, String endTime, String code, String active) {
        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.code = code;
        this.active = active;
        SearchResponse response = getCallFrameServiceResponse();
        ArrayList<ServiceInfo> arrayList = new ArrayList<>();
        if (response.getHits().totalHits() != 0) {
            StringTerms servicesStringTerms = (StringTerms) response.getAggregations().getAsMap().get("frameName");
            Iterator<Terms.Bucket> iterator = servicesStringTerms.getBuckets().iterator();
            while (iterator.hasNext()) {
                Terms.Bucket next = iterator.next();
                String frameName = (String) next.getKey();
                long docCount = next.getDocCount();
                arrayList.add(new ServiceInfo(frameName, docCount, ""));
            }
        }
        return arrayList;
    }


}
